跳到主要内容

Kubernetes 网络配置

Service 是什么?

Kubernetes 的 Service 是一种抽象的概念,用于定义一组 Pod 的访问方式和网络规则。Service 可以为应用程序提供一个稳定的网络终结点,使得其他应用程序或用户可以通过该终结点访问到运行在 Kubernetes 集群中的 Pod。

Service 的实现是通过在 Kubernetes 集群内部创建一个虚拟的服务 IP 地址和负载均衡机制来实现的。

当创建一个Service时,Kubernetes 会为该 Service 分配一个唯一的虚拟 IP 地址,并将该 IP 地址绑定到一个专用的 Service 代理上。Service 代理负责将接收到的请求转发到后端的 Pod 上,以实现负载均衡和服务发现的功能。

在 Service 的背后,Kubernetes 使用标签选择器(Label Selector)来定义与 Service 关联的 Pod。通过标签选择器,Service可以将请求路由到具有相应标签的 Pod 上。

当一个新的 Pod 加入到集群中,并且具有与 Service 关联的标签时,Service 会自动将该 Pod 添加到负载均衡池中,从而实现自动服务发现和负载均衡。

Service 还支持不同的访问模式,包括 ClusterIP、NodePort 和LoadBalancer。

  • ClusterIP 模式将 Service 暴露在集群的内部网络中;
  • NodePort 模式将 Service 映射到每个节点的固定端口上;
  • LoadBalancer 模式则通过云提供商的负载均衡器将外部流量转发到Service。

总之,Kubernetes 的 Service 是一个抽象层,为应用程序提供了一个稳定的网络终结点,并通过标签选择器和负载均衡机制实现自动服务发现和请求路由。

Kubernetes 中的 Service

Service 的分类

在 Kubernetes 中,Service(服务)根据其暴露和负载均衡的方式可以分为以下几种类型:

  1. ClusterIP:ClusterIP 是默认的 Service 类型。它为服务分配一个集群内部的虚拟 IP 地址,只能从集群内部访问。适用于在集群内部进行服务发现和通信的场景。

  2. NodePort:NodePort 类型的 Service 会在每个集群节点上选择一个端口,并将流量转发到指定的 Service。它会将集群内部的虚拟 IP 地址与每个节点上的选定端口关联起来,从而可以通过节点的 IP 地址和选定端口从集群外部访问该 Service。

  3. LoadBalancer:LoadBalancer 类型的 Service 在云平台上创建一个负载均衡器,并将流量均衡到后端的 Service。这个类型需要底层云提供商支持,并会为 Service 分配一个外部可访问的 IP 地址。适用于需要在集群外部公开服务的情况。

  4. ExternalName:ExternalName 类型的 Service 允许将 Kubernetes Service 映射到集群外部的任意域名。它通过返回外部域名的 CNAME 记录,使得集群内的 Pod 可以通过这个域名进行访问。

  5. Headless:Headless 类型的 Service 用于关闭负载均衡功能,直接将 DNS 查找返回 Service 中的所有后端 Pod 的 IP 地址列表。适用于需要直接与每个 Pod 进行通信的场景。

这些 Service 类型可以根据不同的需求选择,以实现对服务的适当暴露和负载均衡。你可以根据你的具体场景和需求选择最适合的 Service 类型。

Label 选择器

Deployment、StatefulSet 这类工作负载都是通过 labelSelector 来管理一组 Pod 的。那么 Kubernetes 中的 Service 也采用了同样的做法,如下图。

这样一个 Service 会选择集群所有 label 中带有 app = nginxenv = prod 的 Pod。

# nginx-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-prod-svc-demo
namespace: demo # service 是 namespace 级别的对象
spec:
selector: # Pod选择器
app: nginx
env: prod
type: ClusterIP # service 的类型
ports:
- name: http
port: 80 # service 的端口号
targetPort: 80 # 对应到 Pod 上的端口号
protocol: TCP # 还支持 udp,http 等

如下一个 Deployment 的定义,可以发现服务定义的选择器可以命中 template 里面的 labels:

# nginx-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-prod-deploy
namespace: demo
labels:
app: nginx
env: prod
spec:
replicas: 3
selector:
matchLabels:
app: nginx
env: prod
template:
metadata:
labels:
app: nginx
env: prod
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80

启动服务

$ kubectl create -f nginx-svc.yaml
$ kubectl create -f nginx-deploy.yaml
$ kubectl get deploy -n demo

$ kubectl get pod -n demo -o wide

再来检查一下服务

$ kubectl get svc -n demo

可以看到,这个 Service 分配到了一个地址为 10.107.52.81 的 Cluster IP,这是一个虚拟 IP(VIP)地址,集群内所有的 Pod 和 Node 都可以通过这个虚拟 IP 地址加端口的方式来访问该 Service。

这个 Service 会根据标签选择器,把匹配到的 Pod 的 IP 地址都挂载到后端。

我们使用 kubectl describe 来看看这个 Service:

可以看到,这时候 Service 关联的 Endpoints 里面有三个 IP 地址。

我们试着来缩容 Deployment 的副本数,再来看看 Service 关联的 Pod IP 地址有什么变化:

$ kubectl scale --replicas=2 deploy -n demo nginx-prod-deploy
$ kubectl get pod -n demo -o wide

$ kubectl describe svc -n demo nginx-prod-svc-demo

可见当 Pod 的生命周期发生变化时,比如缩容或者异常退出,Service 会自动把有问题的 Pod 从后端地址中摘除。这样实现的好处在于,我们可以始终通过一个虚拟的稳定 IP 地址来访问服务,而不用关心其后端真正实例的变化。

集群内如何访问 Service?

一般来说,在 Kubernetes 集群内,我们有两种方式可以访问到一个 Service。

使用虚拟 IP 去访问

如果该 Service 有 ClusterIP,我们就可以直接用这个虚拟 IP 去访问。

比如我们上面创建的 nginx-prod-svc-demo 这个 Service,我们通过 kubectl get svc nginx-prod-svc-demo -n demokubectl get svc nginx-prod-svc-demo -n demo 就可以看到其 Cluster IP 为 10.107.52.81,端口号为 80。

那么我们通过 http(s)://10.107.52.81:80 就可以访问到该服务。

使用 Service 名称去访问

也可以使用该 Service 的域名,依赖于集群内部的 DNS 即可访问。还是以上面的例子做说明,同 namespace 下的 Pod 可以直接通过 nginx-prod-svc-demo 这个 Service 名去访问。

http://my-service.my-namespace

如果是不同 namespace 下的 Pod 则需要加上该 Service 所在的 namespace 名,即 nginx-prod-svc-demo.demo 去访问。

如果在某个 namespace 下,Service 先于 Pod 创建出来,那么 kubelet 在创建 Pod 的时候,会自动把这些 namespace 相同的 Service 访问信息当作环境变量注入 Pod 中,即 {SVCNAME}_SERVICE_HOST{SVCNAME}_SERVICE_PORT

这里 SVCNAME 对应是各个 Service 的大写名称,名字中的横线会被自动转换成下划线。比如:

$ kubectl exec -it nginx-prod-deploy-5dcb88d4cd-cdcl8 -n demo sh

知道了这两种访问方式,我们就可以在启动 Pod 的时候,通过注入环境变量、启动参数或者挂载配置文件等方式,来指定要访问的 Service 信息。

如果是同 namespace 的 Pod,可以直接从自己的环境变量中知道同 namespace 下的其他 Service 的访问方式。

k8s 辨析 port、NodePort、targetPort、containerPort 区别

NodePort

nodePort 提供了集群外部客户端访问 Service 的一种方式,nodePort 提供了集群外部客户端访问 Service 的端口,通过 nodeIP:nodePort 提供了外部流量访问 k8s 集群中 service 的入口。

比如外部用户要访问k8s集群中的一个Web应用,那么我们可以配置对应 service 的 type=NodePort,nodePort=30001。其他用户就可以通过浏览器 http://node:30001 访问到该web服务。

而数据库等服务可能不需要被外界访问,只需被内部服务访问即可,那么我们就不必设置service的NodePort。

而数据库等服务可能不需要被外界访问,只需被内部服务访问即可,那么我们就不必设置 service 的 NodePort。

port

port 是暴露在 clusterIP 上的端口,port 提供了集群内部客户端访问 service 的入口,即 clusterIP:port

mysql 容器暴露了 3306 端口(参考 DockerFile),集群内其他容器通过 33306 端口访问 mysql 服务,但是外部流量不能访问 mysql 服务,因为 mysql 服务没有配置 NodePort。对应的 service.yaml 如下:

apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
ports:
- port: 33306
targetPort: 3306
selector:
name: mysql-pod

targetPort

targetPort 是 pod 上的端口,从 port/nodePort 上来的数据,经过 kube-proxy 流入到后端 pod 的 targetPort 上,最后进入容器。

与制作容器时暴露的端口一致(使用 DockerFile 中的 EXPOSE),例如官方的 nginx(参考DockerFile)暴露80端口。 对应的 service.yaml 如下:

apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort # 配置NodePort,外部流量可访问k8s中的服务
ports:
- port: 30080 # 服务访问端口,集群内部访问的端口
targetPort: 80 # pod控制器中定义的端口(应用访问的端口)
nodePort: 30001 # NodePort,外部客户端访问的端口
selector:
name: nginx-pod

containerPort

containerPort是在pod控制器中定义的、pod中的容器需要暴露的端口。

例如,mysql 服务需要暴露 3306 端口,redis 暴露 6379 端口

apiVersion: v1
kind: ReplicationController
metadata:
name: redis-master
labels:
name: redis-master
spec:
replicas: 1
selector:
name: redis-master
template:
metadata:
labels:
name: redis-master
spec:
containers:
- name: master
image: kubeguide/redis-master
ports:
- containerPort: 6379 # 此处定义暴露的端口

K8s 中端口被占用了怎么办?

注意:如果是使用 Helm 部署的应用,删除之后需要等一会才会释放端口,因为 Helm 会等待一段时间再删除资源。

当你收到 is invalid: spec.ports[0].nodePort: Invalid value: <port_number>: provided port is already allocated 的错误消息时,这表示你在尝试为 Kubernetes Service 中的 nodePort 指定一个已经被占用的端口号。要解决这个问题,可以按照以下步骤进行排查:

1、检查端口号:确保你要分配的 nodePort 端口号是正确的,并且没有被其他进程或服务占用。

sudo lsof -i :<port_number>
# or
sudo netstat -tuln | grep <port_number>

2、使用 kubectl 命令:运行以下命令来检查该端口号是否已经被使用:

kubectl get services --all-namespaces -o wide
kubectl get svc -A | grep <port_number>

这将列出所有命名空间中的服务,并显示每个服务的详细信息,包括 nodePort 端口号。检查输出结果,确认你要使用的 nodePort 没有被其他服务占用。

集群内部的负载均衡如何实现?

这一切都是通过 kube-proxy 来实现的。所有的节点上都会运行着一个 kube-proxy的服务,主要监听 Kubernetes 中的 Service 和 Endpoints。

当 Service 或 Endpoints 发生变化时,就会调用相应的接口创建对应的规则出来,常用模式主要是 iptables 模式和 IPVS 模式。

目前 kube-proxy 默认的工作方式是 iptables 模式,我们来通过如下一个 iptables 模式的例子来看一下实际访问链路是什么样的。

当你通过 Service 的域名去访问时,会先通过 CoreDNS 解析出 Service 对应的 Cluster IP,即虚拟 IP。然后请求到达宿主机的网络后,就会被 kube-proxy 所配置的 iptables 规则所拦截,之后请求会被转发到每一个实际的后端 Pod 上面去,这样就实现了负载均衡。

共享 Network 命名空间

由于一个 pod 中的容器运行于相同的 Network 命名空间中,因此它们共享相同的 IP 地址和端口空间。 这意味着在同一 pod 中的容器运行的多个进程需要注意不能绑定到相同的端口号,否则会导致端口冲突,但这只涉及同一 pod 中的容器。

由于每个 pod 都有独立的端口空间,对于不同 pod 中的容器来说则永远不会遇到端口冲突。此外, 一个 pod 中的所有容器也都具有相同的 loopback 网络接口,因此容器可以通过 localhost 与同一 pod 中的其他容器进行通信。

Service 一直处于 Pending 状态

1、如果你创建一个侦听端口 80 的 LoadBalancer Service,ServiceLB 将尝试在集群中为端口 80 寻找空闲主机。如果没有该端口可用的主机,则 LB 将停留在 Pending 状态。

在同一个 Nodes 里面使用 LoadBalancer 同个端口,会导致一直 Pending,这是由于Kubernetes的网络配置和负载均衡机制引起的。

当你创建一个 LoadBalancer 类型的 Service 时,Kubernetes 会尝试使用云提供商(如AWS、GCP)或集群中的其他负载均衡器来创建一个外部负载均衡器,并将流量转发到 Service 后面的 Pod。然而,当你在同一个节点上创建多个使用相同端口的 LoadBalancer 类型的 Service 时,Kubernetes 无法将流量正确地分发给这些服务,因为它们都监听相同的端口。

当 Kubernetes 尝试创建第二个 LoadBalancer 时,由于第一个 LoadBalancer 已经使用该端口,创建第二个 LoadBalancer 的请求将处于 Pending 状态,直到超时或资源可用。这导致第二个 Service 无法成功创建负载均衡器并将流量转发到 Pod。

为了解决这个问题,你可以考虑以下几种方法:

  1. 使用不同的端口:将不同的Service配置为监听不同的端口,以避免端口冲突,并允许Kubernetes为每个Service创建独立的负载均衡器。

  2. 使用 Ingress:使用 Ingress 控制器来管理流量,并在 Ingress 规则中定义不同的路径或域名来路由流量到不同的服务。这样,你可以使用相同的端口,但根据路径或域名来将流量路由到不同的 Service。

  3. 使用 NodePort:如果你不需要外部负载均衡器,可以考虑使用 NodePort 类型的 Service。 NodePort 会将 Service 暴露在每个节点的固定端口上,并将流量转发到后端 Pod。这样,每个 Service 可以使用不同的 NodePort,并避免冲突。

Pod 的网络是怎么样的?

上面提到了,同一个 Pod 里面的容器共享一个网络命名空间(network namespace),所以,pod 里面的容器之间通信,可以直接通过 localhost 来完成

那么 pod 和 pod 之间的通信呢?

每个 pod 都会有一个自己的 ip,可以将 Pod 像 VM 或物理主机一样对待。这样 pod 和 pod 之间的通信就不需要像容器一样,通过内外端口映射来通信了,这样就避免了端口冲突的问题。

Kubernetes 集群中的所有 pod 都在同一个网段中(相同的网络地址),如下图

这样每个 pod 都可以通过其他 pod 的 IP 地址来实现相互访问。 换句话说,这也表示它们之间没有 NAT(网络地址转换) 网关。

Pod 之间的通讯采用虚拟二层网络技术来实现,比较多使用的是 Flannel

Flannel 实现 pod 之间的通信,是通过一种覆盖网络(overlay network),把数据包封装在另外一个网络来做转发,这个覆盖网络可以给每一个 pod 分配一个独立的 ip 地址,使他们看起来都是一台具有独立 ip 的物理主机一样。

TODO: 继续学习 Flannel 的工作原理...

ingress 怎么使用?

ingress 是干什么的?

Ingress 是 Kubernetes 中的一个资源对象,它充当了集群内部服务与集群外部之间的入口点和流量路由器。

在 Kubernetes 中,内部的服务通常通过 ClusterIP 或 NodePort 类型的 Service 暴露出来,这些服务只能在集群内部访问。然而,当您希望从集群外部访问服务时,需要一种机制来将流量引导到适当的服务。这就是 Ingress 的作用。

通过使用 Ingress 资源对象,可以定义路由规则、域名和路径映射,以将外部流量转发到集群内的不同服务。Ingress 控制器(如 Nginx Ingress Controller 或 Traefik)负责监听 Ingress 资源的变化,并根据定义的规则将流量转发到相应的后端服务。

ingress 与 service 的关系

Ingress 控制器是负责监听和处理 Ingress 资源的组件,它根据 Ingress 规则将流量转发到相应的 Service。实际上,Ingress 控制器可以根据 Ingress 规则中定义的路径、主机和其他条件,将请求转发到后端 Service 中的不同 Pod。

简而言之,Service 是用于在 Kubernetes 集群内部公开和访问服务的资源对象,而 Ingress 是用于从集群外部访问服务的资源对象。Service 提供了内部的网络访问机制,而 Ingress 提供了外部流量入口和路由规则的定义。它们可以结合使用,以实现应用程序的完整的网络访问和流量管理。

当使用 Ingress 和 Service 进行交互时,可以使用以下示例来说明其工作方式:

1、部署应用程序服务: 首先,在 Kubernetes 集群中部署一个或多个应用程序服务,例如一个 Web 应用程序。使用 Deployment 或 StatefulSet 来创建 Pod,并通过 Service 将它们暴露出来。

apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp-deployment
spec:
replicas: 3
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp
image: webapp-image
ports:
- containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
selector:
app: webapp
ports:
- protocol: TCP
port: 80

2、创建 Ingress 资源: 接下来,需要创建一个 Ingress 资源,定义将外部流量路由到应用程序服务。下面是一个简单的 Ingress 资源示例:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: webapp-ingress
spec:
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: webapp-service
port:
number: 80

在上面的示例中,Ingress 规则定义了将主机名 example.com 的 HTTP 请求路由到名为 webapp-service 的 Service 的 80 端口。

3、配置 DNS 解析:

为了使 example.com 解析到集群外部的 Ingress 控制器的公共IP地址,需要将相应的 DNS 记录进行配置。

4、流量转发和负载均衡: 当外部请求到达 Ingress 控制器,并且主机名和路径与 Ingress 规则匹配时,Ingress 控制器将流量转发到相应的 Service 和 Pod。在示例中,Ingress 控制器将流量转发到名为 webapp-service 的 Service。

Service 将根据其选择器匹配的标签选择对应的 Pod,并将流量负载均衡到这些 Pod 上。这样,外部请求就可以通过 Ingress 和 Service 与应用程序服务进行交互。

总结起来,Ingress 和 Service 通过配合使用,实现了将外部流量路由到 Kubernetes 集群内的应用程序服务。Ingress 定义了流量路由规则和主机名与服务的映射关系,而 Service 提供了负载均衡和内部网络访问机制。它们共同协作,使得应用程序能够从集群外部访问,并实现负载均衡和流量管理。

ClusterIP 类型的 Service

如果是 ClusterIP 类型的 service 怎么处理?

如果 Ingress Controller 使用 ClusterIP 类型的 Service,则 Ingress Controller 将只能在集群内部访问,无法直接从集群外部访问。ClusterIP 类型的 Service 将为 Ingress Controller 分配一个仅在集群内部可路由的虚拟 IP 地址。

要从集群外部访问使用 ClusterIP 类型的 Ingress Controller,可以使用以下方法之一:

1、通过 Kubernetes 节点的代理方式访问:可以使用 kubectl 命令通过 Kubernetes 节点的代理功能将请求转发到 Ingress Controller。首先,启动代理:

kubectl proxy

然后,可以通过代理访问 Ingress Controller。例如,如果 Ingress 资源名称为 example-ingress,可以使用以下URL访问:

http://localhost:8001/api/v1/namespaces/<namespace>/services/<ingress-controller-service-name>:<ingress-controller-port>/proxy/

其中,<namespace> 是 Ingress Controller 所在的命名空间,<ingress-controller-service-name> 是 Ingress Controller 的 Service 名称, <ingress-controller-port> 是 Ingress Controller 的端口号。

2、使用 Port Forwarding 进行临时访问:可以使用 kubectl port-forward 命令将 Ingress Controller 的端口转发到本地机器上,从而可以直接访问。例如:

kubectl port-forward svc/<ingress-controller-service-name> <local-port>:<ingress-controller-port>

其中,<ingress-controller-service-name> 是 Ingress Controller 的 Service 名称,<local-port> 是本地机器上用于访问的端口号, <ingress-controller-port> 是 Ingress Controller 的端口号。

这些方法仅提供临时的、开发或调试的访问方式。如果需要将 Ingress Controller 暴露给集群外部或公网访问,最好还是将 Service 类型更改为 NodePort 或 LoadBalancer,并相应地配置网络规则和防火墙设置。这样可以通过集群节点的 IP 地址和 NodePort 或公共负载均衡器的 IP 地址访问 Ingress Controller。

kubectl proxy 代理

在使用 Kubernetes 仪表板时发现,它需要通过以下命令开启代理才能访问

# 默认是 8001
sudo kubectl proxy
# 如果想要指定端口
sudo kubectl proxy --port=8009

所以这里就来了解一下 Kubernetes 中的代理

在 K8S 集群中的业务从外部默认是不能访问的,正式环境中,我们需要通过 service, 然后通过 Node 的 IP 地址和 Loadbanlencer 来访问。

但是还有一些简单的方式,其中之一就是 kubectl proxy

如果想通过浏览器或者 curl、wget 等直接访问 K8S Rest API, 可以使用 kubectl proxy, 他是运行 Kubectl 的机器和 Kubernetes apiserver 之间的一个反向代理。

kubectl proxy --port=8080  

这样,就可以在浏览器中(或者是用 curl),通过以下方式访问 K8SAPI 了:

curl http://localhost:8080/api/

在本地运行了 Kubectl proxy 后,除了很方便的可以通过 curl,wget 等命令访问 API,由于 kubectl 可以通过 pod,service 的名字直接访问 pod 中的 app,所以,我们就可以通过 URI 组合,直接访问 Pod 中的应用了:

http://localhost:8080/api/v1/namespaces/YOURNAMESPACE/services/YOURSERVICE:PORT

例如:

http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/

kubectl port-forward 端口映射

在 Kubernetes 中,可以使用 kubectl port-forward 命令将一个或多个 Kubernetes Pod 的本地端口与 Kubernetes 集群内的服务端口进行映射。这种方法最适用于调试和测试,以及快速访问内部端点。

以下是一个使用 kubectl port-forward 命令的简单示例:

kubectl port-forward my-pod 8080:80

在上述示例中,我们将 Kubernetes 集群中的 Pod my-pod 上的端口 80 映射到本地机器上的端口 8080。

随后,在本地浏览器中打开 http://localhost:8080 就可以访问 Kubernetes Pod 内部的服务了,这个服务可以是一个 HTTP Web 服务、一个数据库等。

需要注意的是,在使用 port-forward 命令时,需要保证访问的 Pod 是处于运行状态的。另外,如果你需要同时进行多个端口的映射,可以在命令中指定多个端口号,例如:

kubectl port-forward my-pod 8080:80 9000:9000

此命令将把 Kubernetes Pod 内部的端口 80 映射到本地机器上的端口 8080,并将端口 9000 映射到本地机器上的端口 9000。

一般来说,port-forward 命令最适用于快速地访问 Kubernetes 集群内部的资源,可能是在运行中的 Pod,或者是其他部署在 Kubernetes 集群中的服务。如果你需要在生产环境中将 Kubernetes 服务发布到外部,考虑使用 ingress 或 NodePort 等 Kubernetes 其他机制。

port-forward 和 proxy 的区别

Kubernetes 中的 port-forwardproxy 都是用于将本地端口与 Kubernetes 集群内的服务端口进行映射的工具,但它们的使用场景和原理略有不同。

  • port-forward 可以将 Kubernetes 内部的服务端口暴露到本地机器上。它的原理是创建一个临时的、双向的网络通道,从本地机器到 Kubernetes 集群内的 Pod 上的容器。这种方法最适合用于在集群内部测试服务,而不是在外部使用它们。因为 port-forward 命令只会将 Kubernetes 内部的 Pod 暴露到 localhost 上的一个本地端口上。如果你需要在本地机器上通过网络访问服务,则需要使用 proxy。
  • proxy 是一个可以代理 Kubernetes 服务的 HTTP 代理。Kubernetes Proxy 监听本地机器上的一个端口,并将所有来自此端口的请求代理到正确的服务/端点上。这种方法可以实现许多在内网部署应用的需求,比如通过网关机器将请求代理到 Kubernetes 集群中的某个节点或 Pod 上的某个容器。

总的来说,port-forward 适用于在本地调试和测试 Kubernetes 服务,而 proxy 则更适用于在生产环境中将 Kubernetes 服务发布到外部。

References